package framework.utils;

import org.springframework.util.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class DateUtil {

    /**
     * 最大时间值(UTC)
     */
    public static final ZonedDateTime MAX_UTC_TIME = ZonedDateTime.of(9999, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"));
    /**
     * 最大时间值(本地)
     */
    public static final LocalDateTime MAX_LOCAL_TIME = LocalDateTime.of(9999, 1, 1, 0, 0, 0, 0);

    /**
     * 时间格式(毫秒时区)(Iso8601)
     */
    public static final String FORMAT_MILLI_ZONE = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
    /**
     * 时间格式(时区)(Iso8601)
     */
    public static final String FORMAT_ZONE = "yyyy-MM-dd'T'HH:mm:ssZ";
    /**
     * 时间格式
     */
    public static final String FORMAT_TIME = "yyyy-MM-dd HH:mm:ss";
    /**
     * 时间格式
     */
    public static final String FORMAT_DATE = "yyyy-MM-dd";

    /**
     * 转换为GMT时间，失败则返回 NULL
     *
     * @param str
     * @param dateFormat
     * @return
     */
    public static Date getGMTString(String str, String dateFormat) {
        DateFormat format = new SimpleDateFormat(dateFormat);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        try {
            return format.parse(str);
        } catch (ParseException e) {
//            e.printStackTrace();
        }
        return null;
    }

    /**
     * 转换时间，失败则返回 NULL
     *
     * @param str
     * @param dateFormat
     * @param timeZone
     * @return
     */
    public static Date tryDate(String str, String dateFormat, String timeZone) {
        DateFormat format = new SimpleDateFormat(dateFormat);
        if (StringUtils.hasText(timeZone)) {
            format.setTimeZone(TimeZone.getTimeZone(timeZone));
        }
        try {
            return format.parse(str);
        } catch (ParseException e) {
//            e.printStackTrace();
        }
        return null;
    }

    /**
     * 转换UTC时间，失败则返回 NULL
     *
     * @param str
     * @param dateFormat
     * @return
     */
    public static Date tryUTCDate(String str, String dateFormat) {
        return tryDate(str, dateFormat, "UTC");
    }

    /**
     * 转换为GMT时间，失败则返回当前值
     *
     * @param str
     * @param dateFormat
     * @return
     */
    public static Date tryUTCDateOrNow(String str, String dateFormat) {
        Date date = tryDate(str, dateFormat, "UTC");
        if (date == null) return new Date();
        return date;
    }

    /**
     * 转换为GMT时间，失败则返回 NULL
     *
     * @param str
     * @param dateFormat
     * @param timeZone
     * @return
     */
    public static Date tryDateOrNow(String str, String dateFormat, String timeZone) {
        Date date = tryDate(str, dateFormat, timeZone);
        if (date == null) return new Date();
        return date;
    }

    /**
     * 根据一个给定的日期格式返回当前时间
     *
     * @param format 给定的日期时间格式
     * @return
     */
    public static String getNowString(String format) {
        DateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.format(new Date());
    }

    /**
     * 将日期字符串转换成日期类型
     *
     * @param dateStr 日期字符串
     * @param format  日期字符串的格式。如果没有指定（null或者""）默认为yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static Date stringToDate(String dateStr, String format) {
        if (!StringUtils.hasText(format)) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        if (StringUtils.hasLength(dateStr)) {
            try {
                return new SimpleDateFormat(format).parse(dateStr);
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }

    /**
     * 获取num个月日期
     *
     * @param date
     * @param num
     * @return
     */
    public static Date getDate(Date date, int num) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        //num个月前时间
        calendar.add(calendar.MONTH, num);
        Date time = calendar.getTime();
        return time;
    }

    /**
     * 计算2个日期之间相差的  相差是否小于一年
     * 比如：2011-02-02 到  2017-03-02 相差 6年，1个月，0天
     *
     * @param fromDate
     * @param toDate
     * @return
     */
    public static boolean dayComparePrecise(Date fromDate, Date toDate) {
        boolean flag = true;
        Calendar from = Calendar.getInstance();
        from.setTime(fromDate);
        Calendar to = Calendar.getInstance();
        to.setTime(toDate);
        int fromYear = from.get(Calendar.YEAR);
        int fromMonth = from.get(Calendar.MONTH);
        int fromDay = from.get(Calendar.DAY_OF_MONTH);
        int toYear = to.get(Calendar.YEAR);
        int toMonth = to.get(Calendar.MONTH);
        int toDay = to.get(Calendar.DAY_OF_MONTH);
        int year = toYear - fromYear;
        int month = toMonth - fromMonth;
        int day = toDay - fromDay;
        if (year < 1 || (year == 1 && month == 0 && day == 0)) {
            flag = false;
        }
        return flag;
    }

}
